package com.onpositive.wiki3.db.impl;

import java.util.ArrayList;
import java.util.HashMap;

import com.carrotsearch.hppc.IntOpenHashSet;

public class CategoryRefMap {

	private WikiDBImpl impl;
	protected HashMap<Integer, CatInf> z;
	IntOpenHashSet toIgnore = new IntOpenHashSet();

	public CategoryRefMap(WikiDBImpl wikiDBImpl,String from) {
		this.impl = wikiDBImpl;
		HashMap<Integer, CatInf> buildInfoMap = ((CategoryAccessImpl) impl
				.getCategoryAccessor()).buildInfoMap();
		z = buildInfoMap;
		System.out.println(buildInfoMap.size());
		int id = wikiDBImpl.getTitleMapper().getId(from);
		CatInf m = getInfo(id);
		toIgnore.add(wikiDBImpl.getTitleMapper().getId(
				"All_articles_with_unsourced_statements"));
//		toIgnore.add(wikiDBImpl.getTitleMapper().getId("Tracking_categories"));
//		toIgnore.add(wikiDBImpl.getTitleMapper().getId("Hidden_categories"));
//		toIgnore.add(wikiDBImpl.getTitleMapper().getId("Container_categories"));
//		toIgnore.add(wikiDBImpl.getTitleMapper().getId("Featured_content"));
//		toIgnore.add(wikiDBImpl.getTitleMapper().getId("Categories"));
		toIgnore.add(wikiDBImpl.getTitleMapper().getId(
				"Wikipedia_administration"));
		m.level = 0;
		fill(id);
	}

	int count = 0;

	private void fill(int id) {
		int level = 0;
		IntOpenHashSet tofill = new IntOpenHashSet();
		tofill.add(id);
		while (!tofill.isEmpty()) {
			IntOpenHashSet tofill2 = new IntOpenHashSet();
			for (int q : tofill.toArray()) {
				if (toIgnore.contains(q)) {
					continue;
				}

				CatInf catInf = getInfo(q);
				catInf.level = level;

				if (catInf.cats != null) {
					for (int m : catInf.cats.toArray()) {
						CatInf c1 = getInfo(m);
						if (c1.level > level) {
							// tofill.add(m);

							c1.parentCat = catInf;
							int delta=1;
							String title = impl.getTitleMapper().getTitle(catInf.id);
//							String lowerCase = title.replace(' ', '_').toLowerCase();
//							if (lowerCase.endsWith("_by_type")){
//								delta=0;
//							}
//							if (lowerCase.endsWith("_by_contry")){
//								delta=0;
//							}
//							if (lowerCase.matches("(.)*\\d\\d\\d\\d(\\s)*-(\\s)*\\d\\d\\d\\d")){
//								
//								//System.out.println(title);
//								delta=0;
//							}
							c1.level = level + delta;
							tofill2.add(m);
						} else {
							if (level - c1.level < 8) {
								c1.alterativeParentCats.add(m);
							}
						}
					}
				}

			}
			level++;
			tofill = tofill2;
			System.out.println(level + ":" + tofill2.size());
		}
		// }
	}

	protected CatInf getInfo(int q) {
		CatInf catInf = z.get(q);
		if (catInf == null) {
			catInf = new CatInf(q);
			z.put(q, catInf);
		}
		return catInf;
	}

	public static class CatInf {
		int id;

		public CatInf(int id) {
			super();
			this.id = id;
		}

		IntOpenHashSet cats;

		public IntOpenHashSet getCats() {
			return cats;
		}

		IntOpenHashSet alterativeParentCats = new IntOpenHashSet();

		CatInf parentCat;
		int level = Integer.MAX_VALUE;
	}

	public ArrayList<Integer> getPath(int p) {
		CatInf catInf = getInfo(p);
		ArrayList<Integer> mm = new ArrayList<Integer>();
		while (catInf != null) {
			mm.add(catInf.id);
			catInf = catInf.parentCat;
		}
		System.out.println(mm.size());
		return mm;
	}

	public ArrayList<ArrayList<Integer>> getTopicCloud(int q) {
		int[] parentCategories = impl.getCategoryAccessor()
				.getParentCategories(q, false);
		ArrayList<ArrayList<Integer>> z = new ArrayList<ArrayList<Integer>>();
		for (int qa : parentCategories) {
			z.add(getPath(qa));
		}
		return z;
	}

	protected void ff(int q, IntOpenHashSet m) {

	}

	public IntOpenHashSet findAllGoodRoots(int m) {
		IntOpenHashSet mm=new IntOpenHashSet();
		mm.add(m);
		fillUp(m,mm);
		return mm;
	}

	private void fillUp(int m, IntOpenHashSet mm) {
		for (int q:mm.toArray()){
			CatInf catInf = z.get(q);
			System.out.println(impl.getTitleMapper().getTitle(catInf.id));
			if (catInf.level>0){
				mm.add(catInf.id);
				for (int z:impl.getCategoryAccessor().getParentCategories(catInf.id, false)){
					CatInf catInf2 = this.z.get(z);
					System.out.println(impl.getTitleMapper().getTitle(catInf2.id)+":"+catInf2.level);
					if (catInf2.level<catInf.level){
						fillUp(z,mm);						
					}
				}
			}
		}
	}
}
